package com.wondertek.poms.core.service.impl;

import cn.hutool.core.convert.Convert;
import com.wondertek.poms.common.service.impl.ServiceImpl;
import com.wondertek.poms.core.service.IEquityNodeService;
import com.wondertek.poms.core.service.IEquityTreeService;
import com.wondertek.poms.dao.po.EquityNode;
import com.wondertek.poms.dao.po.EquityTree;
import com.wondertek.poms.dao.po.ProductGroup;
import com.wondertek.poms.dao.pojo.EquityNodePojo;
import com.wondertek.poms.dao.repo.IEquityNodeDao;
import com.wondertek.poms.dao.repo.IEquityTreeDao;
import com.wondertek.poms.dao.repo.IProductGroupDao;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.util.*;

@Service
public class EquityTreeServiceImpl extends ServiceImpl<EquityTree,Long> implements IEquityTreeService {

	@PersistenceContext
    public EntityManager entityManager;
    @Autowired
    private IEquityNodeDao equityNodeDao;
    @Autowired
    private IEquityNodeService equityNodeService;
    @Autowired
    private IEquityTreeDao equityTreeDao;
    @Autowired
    private IProductGroupDao productGroupDao;

    @Override
    public Page<EquityTree> findAll(int page, int rows, String sord, String sidx) {
        String sql="select * from EQUITY_TREE order by "+sidx+" "+sord;
        Object o = entityManager
                .createNativeQuery("select count(*) from ( " + sql + " ) a").getSingleResult();
        int count = Convert.toInt(o);
        Pageable pageable = getPageable(page - 1, rows, sord, sidx);

        if(count>0){
            Query query=entityManager.createNativeQuery(sql,EquityTree.class);
            query.setFirstResult(pageable.getPageNumber()*pageable.getPageSize());
            query.setMaxResults(pageable.getPageSize());
            List<EquityTree> list=query.getResultList();
            PageImpl<EquityTree> result=new PageImpl<>(list,pageable,count);
            entityManager.close();
            return result;
        }
        entityManager.close();
        return Page.empty(pageable);
    }

    @Override
    public EquityNodePojo getAllEquityNodesByTreeId(Long treeId,boolean valid) {
        List<EquityNode> tempList=new LinkedList<>();
        if(valid){
            tempList=equityNodeDao.getValidFirstNodesByTreeId(treeId);
        }else {
            tempList=equityNodeDao.getFirstNodesByTreeId(treeId);
        }
        EquityNode temp=new EquityNode();
        if(tempList!=null && tempList.size()>0){
            temp=tempList.get(0);
            EquityNodePojo equityNodePojo=new EquityNodePojo(temp);
            List<EquityNodePojo> equityNodeList=new ArrayList<>();
            equityNodeList = getAllNodesByParentId(temp.getId(), equityNodeList,valid);
            equityNodePojo.setChildren(equityNodeList);
            return equityNodePojo;
        }else{
            return null;
        }
    }

    /**
     * 通过节点最大的层级设置权益树的深度，树的状态改为待发布
     * @param treeId
     */
    @Override
    public void updateTreeDepth(Long treeId) {
        EquityTree equityTree=jpaRepository.getOne(treeId);
        EquityNode node=new EquityNode();
        Sort sort = new Sort(Sort.Direction.DESC, "hierarchy");
        node.setTreeId(treeId);
        node.setDeleteStatus(0);
        List<EquityNode> pcEquityNodes = equityNodeService.findAll(Example.of(node), sort);
        equityTree.setEquityTreeDepth(pcEquityNodes.get(0).getHierarchy().intValue());
        equityTree.setActiveStatus("2");
        equityTree.setCreateTime(new Date());
        jpaRepository.save(equityTree);
    }

    @Override
    @Transactional
    public void deleteEquityTree(Long treeId) {
        EquityTree equityTree=jpaRepository.getOne(treeId);
        jpaRepository.delete(equityTree);
        List<EquityNode> nodes=equityNodeDao.findAllByTreeIdAndDeleteStatus(treeId,0);
        for(EquityNode node:nodes){
            node.setDeleteStatus(1);
            equityNodeDao.save(node);
        }
    }

    @Override
    public Map<String, Object> getEquityTreeMap(Long treeId) {
        Map<String, Object> map = new HashMap<String, Object>();
        Optional<EquityTree> opt = equityTreeDao.findById(treeId);
        if(opt.isPresent()){
            EquityTree equityTree=opt.get();
            map.put("equityTreeName", equityTree.getEquityTreeName());
            map.put("equityTreeDepth", equityTree.getEquityTreeDepth());
            List<EquityNode> equityNodes = equityNodeDao.findAllByTreeIdAndDeleteStatus(treeId,0);
            List<EquityNodePojo> equities = new ArrayList<>();
            for(EquityNode equityNode : equityNodes){
                String parentEquityNodeId = "0";
                if( equityNode.getParentId()!= 0 ){
                    Optional<EquityNode> equityNodeOpt=equityNodeDao.findById(equityNode.getParentId());
                    if(equityNodeOpt.isPresent()){
                        parentEquityNodeId = equityNodeOpt.get().getEquityNodeId();
                    }
                }
                EquityNodePojo equityNodeVo = new EquityNodePojo(equityNode, parentEquityNodeId);
                equities.add(equityNodeVo);
            }
            map.put("equities", equities);
        }
        return map;
    }

    public List<EquityNodePojo> getAllNodesByParentId(Long id,List<EquityNodePojo> equityNodeList,boolean valid){
        List<EquityNode> equityNodes = new LinkedList<>();
        if(valid){
            equityNodes = equityNodeDao.getValidNodeByParentId(id);
        }else {
            equityNodes = equityNodeDao.getNodeByParentId(id);
        }
        if(equityNodes != null && equityNodes.size() > 0){
            for(EquityNode equityNode : equityNodes){
                EquityNodePojo vo = new EquityNodePojo(equityNode);
                ProductGroup group=new ProductGroup();
                if(valid){
                    group = productGroupDao.findValidByGroupId(equityNode.getGroupId());
                }else {
                    group = productGroupDao.findByGroupId(equityNode.getGroupId());
                }
                if(group != null){
                    vo.setGroupName(group.getGroupName());
                }
                List<EquityNodePojo> childEquityNodeVos = new ArrayList<>();
                childEquityNodeVos = getAllNodesByParentId(equityNode.getId(),childEquityNodeVos,valid);
                vo.setChildren(childEquityNodeVos);
                equityNodeList.add(vo);
            }
        }
        return equityNodeList;
    }


    @Override
    public EquityTree deleteLogic(Long id) {
        return null;
    }

    @Override
    @Transactional
    public EquityTree merge(EquityTree model) {
        model.setCreateTime(new Date());
        return jpaRepository.save(model);
    }
}
